package com.imut.hcdp.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.imut.hcdp.config.exception.ServiceException;
import com.imut.hcdp.domain.*;
import com.imut.hcdp.mapper.*;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.imut.hcdp.service.IHcdpTrainRouteService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


@Service
@Slf4j
public class HcdpTrainRouteServiceImpl implements IHcdpTrainRouteService
{
    @Autowired
    private HcdpTrainRouteMapper hcdpTrainRouteMapper;

    @Autowired
    private HcdpTrainRouteDetailMapper hcdpTrainRouteDetailMapper;

    @Autowired
    private HcdpTrainAllMapper hcdpTrainAllMapper;

    @Autowired
    private HcdpTrainSeatMapper hcdpTrainSeatMapper;

    @Autowired
    private HcdpSeatTypePriceMapper hcdpSeatTypePriceMapper;

    @Autowired
    private HcdpPassengerMapper hcdpPassengerMapper;

    @Autowired
    private HcdpTrainMapper hcdpTrainMapper;

    @Autowired
    private HcdpUserMapper hcdpUserMapper;


    @Override
    public HcdpTrainRoute selectHcdpTrainRouteById(Long id)
    {
        return hcdpTrainRouteMapper.selectHcdpTrainRouteById(id);
    }


    @Override
    public ArrayList<RouteResult> selectHcdpTrainRouteList(HcdpTrainRoute hcdpTrainRoute) throws ParseException {
        ArrayList<RouteResult> routeResults = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfZero = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        SimpleDateFormat sdfMax = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //先进行时间筛选
        HcdpTrainRoute param = new HcdpTrainRoute();
        Date paramDate = hcdpTrainRoute.getParamTime();
        Date nowDate = new Date();
        String paramDatePrase = sdf.format(paramDate);
        String nowDatePrase = sdf.format(nowDate);
        //判断是否为当天车票
        if(paramDatePrase.equals(nowDatePrase)){
            param.setSTime(nowDate);
            param.setETime(sdfMax.parse(nowDatePrase + " 23:59:59" ));
        }else{
            String format = sdfZero.format(paramDate);
            param.setSTime(sdfZero.parse(format));
            param.setETime(sdfMax.parse(paramDatePrase + " 23:59:59"));
        }
        List<Long> checkRoute = hcdpTrainRouteMapper.checkRoute(param);
        if(CollectionUtils.isEmpty(checkRoute)){
            throw new ServiceException("暂无行程信息！");
        }

        List<HcdpTrainRoute> hcdpTrainRoutes = hcdpTrainRouteMapper.getById(checkRoute);
        //过滤主表
        List<HcdpTrainRoute> mainInfo = hcdpTrainRoutes.stream().filter(temp -> {
            if (temp.getSCity().equals(hcdpTrainRoute.getSCity()) && temp.getECity().equals(hcdpTrainRoute.getECity())) {
                RouteResult routeResult = new RouteResult();
                HcdpTrainRoute tempRoute = temp;
                //全路径
                routeResult.setHcdpTrainAll(hcdpTrainAllMapper.selectHcdpTrainAllByRouteId(tempRoute.getId()));
                //始发终点
                routeResult.setStartCity(hcdpTrainRoute.getSCity());
                routeResult.setEndCity(hcdpTrainRoute.getECity());
                //时刻表
                List<RouteDetailResult> routeDetailResults = trainSchedule(tempRoute.getId());
                routeResult.setRouteDetailResultList(routeDetailResults);
                //经停时间(用户搜索区间的)
                JSONObject jsonObject = trainTime(routeDetailResults, hcdpTrainRoute.getSCity(), hcdpTrainRoute.getECity());
                routeResult.setUserSearch(jsonObject);
                //主航程信息
                routeResult.setHcdpTrainRoute(tempRoute);
                //座位信息
                String[] order = hcdpTrainRouteDetailMapper.selectOrderAsc(tempRoute.getId()).split("-");
                routeResult.setSeatPrice(trainSeatPrice(tempRoute.getId(),Long.parseLong(order[0]),Long.parseLong(order[1])));
                //行程id详情
                routeResult.setRouteDetailIds(hcdpTrainRouteDetailMapper.selectDetailIds(tempRoute.getId()));
                routeResults.add(routeResult);
                return true;
            }
            return false;
        }).collect(Collectors.toList());


        //删除冗余信息
        hcdpTrainRoutes.removeAll(mainInfo);

        hcdpTrainRoutes.stream().forEach(temp ->{
            Long id = temp.getId();
            hcdpTrainRoute.setId(id);
            List<HcdpTrainRouteDetail> hcdpTrainRouteDetails = hcdpTrainRouteDetailMapper.selectList(hcdpTrainRoute);
            //找到中途路段
            if(!CollectionUtils.isEmpty(hcdpTrainRouteDetails) && hcdpTrainRouteDetails.size() == 2){

                //获取车票
                HcdpTrainRouteDetail qujianStart = hcdpTrainRouteDetails.get(0);
                HcdpTrainRouteDetail qujianEnd = hcdpTrainRouteDetails.get(1);
                Long startOrder = qujianStart.getOrder();
                Long endOrder = qujianEnd.getOrder();
                Long startOrderParam = Long.min(startOrder,endOrder);
                Long endOrderParam = Long.max(startOrder,endOrder);

                RouteResult routeResult = new RouteResult();
                HcdpTrainRoute tempRoute = temp;
                //全路径
                routeResult.setHcdpTrainAll(hcdpTrainAllMapper.selectHcdpTrainAllByRouteId(tempRoute.getId()));
                //始发终点
                routeResult.setStartCity(hcdpTrainRoute.getSCity());
                routeResult.setEndCity(hcdpTrainRoute.getECity());
                //时刻表
//                routeResult.setRouteDetailResultList(trainSchedule(tempRoute.getId()));
                List<RouteDetailResult> routeDetailResults = trainSchedule(tempRoute.getId());
                routeResult.setRouteDetailResultList(routeDetailResults);
                //经停时间(用户搜索区间的)
                JSONObject jsonObject = trainTime(routeDetailResults, hcdpTrainRoute.getSCity(), hcdpTrainRoute.getECity());
                routeResult.setUserSearch(jsonObject);
                //主航程信息
                routeResult.setHcdpTrainRoute(tempRoute);
                //座位信息
                routeResult.setSeatPrice(trainSeatPrice(tempRoute.getId(),startOrderParam,endOrderParam));
                routeResult.setRouteDetailIds(getDetailIds(startOrderParam,endOrderParam));
                routeResults.add(routeResult);
            }

        });
        return routeResults;
    }

    private String getDetailIds(Long start,Long end){
        StringBuffer stringBuffer = new StringBuffer();
        for (Long i = start; i<= end ; i++){
            stringBuffer.append(i);
            if(!i.equals(end)){
                stringBuffer.append(",");
            }
        }
        return stringBuffer.toString();
    }

    /**
     * 用户搜索后的火车经停时间
     * @param param
     * @return
     */
    private JSONObject trainTime(List<RouteDetailResult> param,String scity,String ecity){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        RouteDetailResult start = param.stream().filter(temp -> temp.getCity().equals(scity)).findFirst().get();
        RouteDetailResult end = param.stream().filter(temp -> temp.getNextCity().equals(ecity)).findFirst().get();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("scity",scity);
        jsonObject.put("ecity",ecity);
        jsonObject.put("startTime",sdf.format(start.getStartTime()));
        jsonObject.put("endTime",sdf.format(start.getEndTime()));
        jsonObject.put("stopTime",getTime(end.getEndTime().getTime() - start.getStartTime().getTime()));
        return jsonObject;
    }

    /**
     * 获取列车时刻表
     * @return
     */
    private List<RouteDetailResult> trainSchedule(Long id){
        ArrayList<RouteDetailResult> resultList = new ArrayList<>();
        HcdpTrainRouteDetail param = new HcdpTrainRouteDetail();
        param.setRouteId(id);
        List<HcdpTrainRouteDetail> details = hcdpTrainRouteDetailMapper.selectHcdpTrainRouteDetailList(param);
        for (int i = 0; i < details.size(); i++) {

            HcdpTrainRouteDetail detail = details.get(i);
            Date sTime = detail.getSTime();
            Date eTime = detail.getETime();
            RouteDetailResult result = new RouteDetailResult();
            result.setNextCity(detail.getECity());
            result.setCity(detail.getSCity());
            result.setStartTime(sTime);
            result.setEndTime(eTime);
            result.setStopTime("");
            result.setRouteId(detail.getRouteId());
            result.setRouteDetailId(detail.getId());
            result.setOrder(detail.getOrder());
            Long waitTimeLong = eTime.getTime() - sTime.getTime();
            if(details.size() - 1 > i){
                HcdpTrainRouteDetail detailNext = details.get(i + 1);
                Date sTime1 = detailNext.getSTime();
                Date eTime1 = detail.getETime();
                String time = getTime(sTime1.getTime() - eTime1.getTime());
                result.setStopTime(time);
            }
            result.setWaitTime(getTime(waitTimeLong));
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取等待时长
     * @param time
     * @return
     */
    private static String getTime(Long time) {
        String timeStr="";
        if (time==null){
            return null;
        }
        time = time / 1000;
        //时
        Long hour = time / 60 / 60;
        //分
        Long minutes = time / 60 % 60;
        //秒
        Long remainingSeconds = time % 60;
        //判断时分秒是否小于10……
        if (hour < 10){
            timeStr =  hour + "时" + minutes + "分" + remainingSeconds+"秒";
        }else if (minutes < 10){
            timeStr =  minutes + "分" + remainingSeconds+"秒";
        }else if (remainingSeconds < 10){
            timeStr =  minutes + "分" + "0" + remainingSeconds+"秒";
        }else {
            timeStr =  minutes + "分" + remainingSeconds+"秒";
        }
        return timeStr;
    }

    /**
     * 座位信息及价位
     * @return
     */
    private List<SeatPrice> trainSeatPrice(Long routeId,Long s,Long e){
        List<Long> seatPricesIds = hcdpTrainRouteMapper.seatPriceIds(routeId, s, e);
        List<SeatPrice> seatPrices =  hcdpTrainRouteMapper.seatPrice(seatPricesIds,routeId);
        //查看余票
        for (int i = 0; i < seatPrices.size(); i++) {
            SeatPrice seatPrice = seatPrices.get(i);
            Long seatId = seatPrice.getSeatId();
            HcdpTrainSeat hcdpTrainSeat = hcdpTrainSeatMapper.selectHcdpTrainSeatById(seatId);
            //总票数
            seatPrice.setTotalTicket(hcdpTrainSeat.getSeatnum());
            //待支付，已支付都算做已出售
            Integer size = 0;
            HashSet<Long> distinct = new HashSet<>();
            for (Long u = s ; u<=e ; u++){
                List<Long> longs = hcdpPassengerMapper.selectHcdpPassengerListByRouteId2(u, seatPrice.getSeatId(),routeId);
                longs.stream().forEach(temp ->{
                    distinct.add(temp);
                });
            }
            seatPrice.setSellTicket(distinct.size());
            //可购买票数
            seatPrice.setSurplusTicket(hcdpTrainSeat.getSeatnum() - seatPrice.getSellTicket());
        }
        return seatPrices;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertHcdpTrainRoute(HcdpAddTrainRouteParam param)
    {
        Long routeId = param.getRouteId();
        if(routeId != null){
            hcdpTrainAllMapper.deleteHcdpTrainAllByRouteId(routeId);
            hcdpSeatTypePriceMapper.deleteHcdpSeatTypePriceById(routeId);
            hcdpTrainRouteDetailMapper.deleteHcdpTrainRouteDetailByRouteId(routeId);
            hcdpTrainRouteMapper.deleteHcdpTrainRouteById(routeId);
        }

        Date sTime = param.getStime();
        if(sTime.getTime() - System.currentTimeMillis() < 1000 * 60 * 60 * 24 * 7){
            throw new ServiceException("发车时间应设置为7天后日期！");
        }
        Long trainId = param.getTrainId();
        Long crtUser = param.getCrtUser();
        HcdpTrain hcdpTrain = hcdpTrainMapper.selectHcdpTrainById(trainId);
        HcdpUser hcdpUser = hcdpUserMapper.selectHcdpUserById(crtUser);
        //新增全行程
        HcdpTrainRoute hcdpTrainRoute = new HcdpTrainRoute();
        hcdpTrainRoute.setSCity(param.getScity());
        hcdpTrainRoute.setECity(param.getEcity());
        hcdpTrainRoute.setSStation(param.getSstation());
        hcdpTrainRoute.setEStation(param.getEstation());
        hcdpTrainRoute.setSTime(param.getStime());
        hcdpTrainRoute.setETime(param.getEtime());
        hcdpTrainRoute.setTrainid(trainId);
        hcdpTrainRoute.setTraincode(hcdpTrain.getCode());
        hcdpTrainRoute.setCrttime(new Date());
        hcdpTrainRoute.setStatus(1L); //待发车
        hcdpTrainRoute.setCrtuser(hcdpUser.getUsername());
        hcdpTrainRoute.setCrtuserid(hcdpUser.getId());
        int i = hcdpTrainRouteMapper.insertHcdpTrainRoute(hcdpTrainRoute);
        log.info("全行程是否新增成功：{}",i == 1?"是":"否");
        //新增全路线
        List<HcdpTrainRouteDetailParam> routeDetailList = param.getRouteDetailList();
        if(CollectionUtils.isEmpty(routeDetailList)){
            throw new ServiceException("中途路线集合为空！请重新提交数据！");
        }
//        String[] strings = new String[routeDetailList.size() + 1];
        JSONArray strings = new JSONArray();
        for (int j = 0; j < routeDetailList.size(); j++) {
            HcdpTrainRouteDetailParam detailParam = routeDetailList.get(j);
            //添加全线路
            strings.add(detailParam.getScity());
            if(j == routeDetailList.size() - 1){
                strings.add(detailParam.getEcity());
            }
            //添加中途站
            HcdpTrainRouteDetail de = new HcdpTrainRouteDetail();
            de.setECity(detailParam.getEcity());
            de.setSCity(detailParam.getScity());
            de.setETime(detailParam.getEtime());
            de.setSTime(detailParam.getStime());
            de.setRouteId(hcdpTrainRoute.getId());
            de.setTrainId(hcdpTrain.getId());
            de.setTrainCode(hcdpTrain.getCode());
            de.setEStation(detailParam.getEstation());
            de.setSStation(detailParam.getSstation());
            de.setOrder(j + 1L);
            int i1 = hcdpTrainRouteDetailMapper.insertHcdpTrainRouteDetail(de);
            log.info("中途站：{} 是否新增成功：{}",j+1,i1 == 1?"是":"否");

            //添加座位信息及价格
            List<SeatParam> seatParams = detailParam.getSeatParams();
            if(CollectionUtils.isEmpty(seatParams)){
                throw new ServiceException("座位及价格信息为空");
            }
            for (int k = 0; k < seatParams.size(); k++) {
                SeatParam seatParam = seatParams.get(k);
                HcdpTrainSeat hcdpTrainSeat = hcdpTrainSeatMapper.selectHcdpTrainSeatById(seatParam.getId());
                HcdpSeatTypePrice hcdpSeatTypePrice = new HcdpSeatTypePrice();
                hcdpSeatTypePrice.setRouteId(hcdpTrainRoute.getId());
                hcdpSeatTypePrice.setEoutrDetailId(de.getId());
                hcdpSeatTypePrice.setSeatId(seatParam.getId());
                hcdpSeatTypePrice.setSeatTypeName(hcdpTrainSeat.getSeattype());
                hcdpSeatTypePrice.setSeatTypePrice(new BigDecimal(seatParam.getPrice()));
                int i2 = hcdpSeatTypePriceMapper.insertHcdpSeatTypePrice(hcdpSeatTypePrice);
                log.info("中途站：{} 座位：{}",j+1,hcdpTrainSeat.getSeattype(),i2 == 1?"是":"否");
            }

        }
        HcdpTrainAll hcdpTrainAll = new HcdpTrainAll();
        hcdpTrainAll.setRouteId(hcdpTrainRoute.getId());
        hcdpTrainAll.setRoute(strings.toJSONString());
        int i3 = hcdpTrainAllMapper.insertHcdpTrainAll(hcdpTrainAll);
        log.info("全线路常量表是否新增成功：{}",i3 == 1?"是":"否");
        return 1;
    }


    @Override
    public int updateHcdpTrainRoute(HcdpTrainRoute hcdpTrainRoute)
    {
        return hcdpTrainRouteMapper.updateHcdpTrainRoute(hcdpTrainRoute);
    }


    @Override
    public int deleteHcdpTrainRouteByIds(Long[] ids)
    {
        return hcdpTrainRouteMapper.deleteHcdpTrainRouteByIds(ids);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteHcdpTrainRouteById(Long id)
    {
        hcdpTrainAllMapper.deleteHcdpTrainAllByRouteId(id);
        hcdpSeatTypePriceMapper.deleteHcdpSeatTypePriceById(id);
        hcdpTrainRouteDetailMapper.deleteHcdpTrainRouteDetailByRouteId(id);
        return hcdpTrainRouteMapper.deleteHcdpTrainRouteById(id);
    }

    @Override
    public List<AdminRouteResult> list(HcdpTrainRoute hcdpTrainRoute) {
        ArrayList<AdminRouteResult> result = new ArrayList<>();

        //主航线信息
        List<HcdpTrainRoute> hcdpTrainRoutes = hcdpTrainRouteMapper.selectHcdpTrainRouteList(hcdpTrainRoute);
        if(CollectionUtils.isEmpty(hcdpTrainRoutes)){
            return null;
        }
        for (int i = 0; i < hcdpTrainRoutes.size(); i++) {
            ArrayList<HcdpTrainRouteDetailResult> param = new ArrayList<>();
            AdminRouteResult rs = new AdminRouteResult();
            HcdpTrainRoute temp = hcdpTrainRoutes.get(i);
            Long routeId = temp.getId();
            //全程城市信息
            HcdpTrainAll hcdpTrainAll = hcdpTrainAllMapper.selectHcdpTrainAllByRouteId(routeId);
            //中途站信息
            List<HcdpTrainRouteDetail> details = hcdpTrainRouteDetailMapper.selectHcdpTrainRouteDetailList(new HcdpTrainRouteDetail().setRouteId(routeId));
            for (int i1 = 0; i1 < details.size(); i1++) {
                HcdpTrainRouteDetailResult hcdpTrainRouteDetailResult = new HcdpTrainRouteDetailResult();
                HcdpTrainRouteDetail hcdpTrainRouteDetail = details.get(i1);
                Long detailId = hcdpTrainRouteDetail.getId();

                List<HcdpSeatTypePrice> hcdpSeatTypePrices = hcdpSeatTypePriceMapper.selectHcdpSeatTypePriceList(new HcdpSeatTypePrice().setEoutrDetailId(detailId));

                hcdpTrainRouteDetailResult.setHcdpTrainRouteDetail(hcdpTrainRouteDetail);
                hcdpTrainRouteDetailResult.setHcdpSeatTypePrice(hcdpSeatTypePrices);
                param.add(hcdpTrainRouteDetailResult);
            }
            rs.setHcdpTrainRoute(temp);
            rs.setHcdpTrainAll(hcdpTrainAll);
            rs.setHcdpTrainRouteDetailResult(param);
            result.add(rs);
        }
        return result;
    }
}
